/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.ruchin.tek.employees.data;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.*;

/**
 * @author yruchin
 */
public class EmployeeStorage {
    public static final String CONTEXT_KEY = "ru.ruchin.tek.employees.data.EmployeeStorage";

    private EntityManager   entityManager;
    private UserTransaction utx;

    public EmployeeStorage(EntityManager entityManager, UserTransaction utx) {
        this.entityManager = entityManager;
        this.utx = utx;
    }

    public Employee getEmployeeById(long id) {
        return entityManager.find(Employee.class, id);
    }
 
    public Collection<Department> getDepartments() {
        Query q = entityManager.createQuery("SELECT d FROM Department d");
        List<Department> list = q.getResultList();
        
        return Collections.unmodifiableList(list);
    }

    public Department getDepartmentById(long id) {
        return entityManager.find(Department.class, id);
    }

    public boolean saveDepartment(Department department) {
        if (beginTransaction()) {
            entityManager.persist(department);
            return commitTransaction();
        }
        return false;
    }
    
    public boolean updateDepartment(Department department) {
        if (beginTransaction()) {
            entityManager.merge(department);
            return commitTransaction();
        }
        return false;
    }
    
    public boolean saveDepartments(Collection<Department> departments) {
        if (beginTransaction()) {
            for (Department d : departments) {
                entityManager.persist(d);
            }
            return commitTransaction();
        }
        return false;
    }

    public boolean removeEmployee(long id) {
        if (beginTransaction()) {
            Employee e = entityManager.find(Employee.class, id);
            Department d = e.getDepartment();
            d.removeEmployee(e);
            entityManager.remove(e);
            return commitTransaction();
        }
        return false;
    }

    public boolean removeDepartment(long id) {
        if (beginTransaction()) {
            entityManager.remove(entityManager.find(Department.class, id));
            return commitTransaction();
        }
        return false;
    }
    
    public boolean updateEmployee(Employee employee) {
        if (beginTransaction()) {
            entityManager.merge(employee);
            return commitTransaction();
        }
        return false;
    }

    public boolean saveEmployee(Employee employee) {
        if (beginTransaction()) {
            entityManager.persist(employee);
            return commitTransaction();
        }
        
        return false;
    }
    
    private boolean beginTransaction() {
        try {
            utx.begin();
        
            return true;
        } catch (NotSupportedException ex) {
            Logger.getLogger(EmployeeStorage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(EmployeeStorage.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return false;
    }
    
    private boolean commitTransaction() {
        try {
            utx.commit();
            
            return true;
        } catch (RollbackException ex) {
            Logger.getLogger(EmployeeStorage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicMixedException ex) {
            Logger.getLogger(EmployeeStorage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicRollbackException ex) {
            Logger.getLogger(EmployeeStorage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(EmployeeStorage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalStateException ex) {
            Logger.getLogger(EmployeeStorage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(EmployeeStorage.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return false;
    }
}
